First unique character in a string¶
Time: O(N); Space: O(N); easy
Given a string, find the first non-repeating character in it and return it’s index. If it doesn’t exist, return -1.
Example 1:
Input: s = “leetcode”
Output: 0
Example 2:
Input: s = “loveleetcode”
Output: 2
Note:
You may assume the string contain only lowercase letters.
1. Linear time solution [O(N), O(N)]¶
The best possible solution here could be of a linear time because to ensure that the character is unique you have to check the whole string anyway.
The idea is to go through the string and save in a hash map the number of times each character appears in the string. That would take O(N) time, where N is a number of characters in the string.
And then we go through the string the second time, this time we use the hash map as a reference to check if a character is unique or not. If the character is unique, one could just return its index. The complexity of the second iteration is O(N) as well.
[6]:
import collections
class Solution1(object):
"""
Time: O(N) since we go through the string of length N two times.
Space: O(N) since we have to keep a hash map with N elements.
"""
def firstUniqChar(self, s) -> int:
"""
:type s: str
:rtype: int
"""
# build hash map : character and how often it appears
count = collections.Counter(s)
# find the index
for idx, ch in enumerate(s):
if count[ch] == 1:
return idx
return -1
[7]:
sol = Solution1()
s = "leetcode"
assert sol.firstUniqChar(s) == 0
s = "loveleetcode"
assert sol.firstUniqChar(s) == 2
2. Linear time solution [O(N), O(N)]¶
[8]:
from collections import defaultdict
class Solution2(object):
"""
Time: O(N)
Space: O(N)
"""
def firstUniqChar(self, s) -> int:
"""
:type s: str
:rtype: int
"""
lookup = defaultdict(int)
candidtates = set()
for i, c in enumerate(s):
if lookup[c]:
candidtates.discard(lookup[c])
else:
lookup[c] = i+1
candidtates.add(i+1)
return min(candidtates)-1 if candidtates else -1
[9]:
sol = Solution2()
s = "leetcode"
assert sol.firstUniqChar(s) == 0
s = "loveleetcode"
assert sol.firstUniqChar(s) == 2